import { useEffect, useState } from 'react';
import { Button, message, Modal, List, Spin } from 'antd'
import { secondsToMinutes } from '@/utils'
import { getWorkStationList, orderWorkStation, cancelWorkStation, getShinyStatus } from '@/service'
import { useTranslation } from 'react-i18next';
import { useWebSocket } from '@/WebSocketContext';

import styles from './index.module.scss';

export default props => {
    const { t } = useTranslation();
    const [messageApi, contextHolder] = message.useMessage();
    const { socket } = useWebSocket();
    const initState = () => ({
        loadingWork: true,
        workList: [],
    });
    const [state, setState] = useState(initState);

    // 请求工作台列表
    const getOrderList = () => {
        getWorkStationList().then(res => {
            setState(o => ({...o, loadingWork: false}));

            if (res.code == 0) {
                setState(o => ({
                    ...o,
                    workList: res?.data || [],
                }));
            } else {
                messageApi.open({
                    type: 'error',
                    content: res?.msg,
                });
            }
        }).catch(e => {
            setState(o => ({...o, loadingWork: false}));
            messageApi.open({
                type: 'error',
                content: e?.msg,
            });
        });
    }
    // 预约工作台
    const orderWork = (wordId, appId) => {
        let param = { shinyappIds: appId };

        orderWorkStation(wordId, param).then(res => {
            if (res.code == 0) {
                messageApi.open({
                    type: 'success',
                    content: res?.msg,
                });
                // 刷新工作台列表，状态肯定有变更
                getOrderList();

                // 如果空闲就直接获取跳转地址，进入到app页面；如果工作站CPU超过设置，这里应该去排队
                const data = res.data;
                if (data.userNumInfront == 0 && data.shinyAppUrl.length > 0) {
                    getShinyServerFn(wordId, data?.shinyAppUrl);
                }
            } else {
                console.log(res);
                messageApi.open({
                    type: 'error',
                    content: res?.msg,
                });
            }
        }).catch(e => {
            console.log(e);
            messageApi.open({
                type: 'error',
                content: e?.msg,
            });
        });
    }
    // 取消预约工作台
    const cancelWork = (id) => {
        return new Promise((resolve, reject) => {
            cancelWorkStation(id).then(res => {
                if (res.code == 0) {
                    messageApi.open({
                        type: 'success',
                        content: res?.msg,
                    });

                    getOrderList();

                    resolve();
                } else {
                    reject();
                    messageApi.open({
                        type: 'error',
                        content: res?.msg,
                    });
                }
            }).catch(e => {
                messageApi.open({
                    type: 'error',
                    content: e?.msg,
                });
                reject();
            });
        });
    }
    // 获取跳转地址
    const getShinyServerFn = (id, shinyAppUrl) => {
        getShinyStatus(id).then(res => { 
            if (res.code == 0) {
                (shinyAppUrl || []).forEach((url, index) => {
                    setTimeout(() => {
                        window.open(url, '_blank','noopener,noreferrer');
                    }, 1000 * (index + 1));
                });
            } else {
                setTimeout(getShinyServerFn, 3000);
            }
        }).catch(e => {
            setTimeout(getShinyServerFn, 3000);
        });
    }

    // 预约、取消预约app；如果工作站超过配置阈值，那么就去排队
    const handleApp = (work, app) => {
        const inOrder = [15].includes(app.usageStatus);
        const isOver = !!work.overload;

        // 如果在排队，那么就让用户决定是取消排队，还是继续等待
        if(inOrder) {
            Modal.confirm({
                title: t('menu.home.hasOrder').replace('{}', app.shinyappName),
                icon: null,
                content: '',
                onOk() {
                    return cancelWork(app.id);
                },
                okText: t('common.modal.button.submit'),
                cancelText: t('common.modal.button.cancel'),
                onCancel() {},
            });

            return;
        }

        orderWork(work.id, app.id);
    };

    const updateDataArray = (newData) => {
        newData.forEach(updateItem => {
            if (updateItem?.lineUpInfo?.userNumInfront == 0 && updateItem?.lineUpInfo?.shinyAppUrl && updateItem?.lineUpInfo?.shinyAppUrl.length > 0) {
                getShinyServerFn(updateItem.id, updateItem?.lineUpInfo?.shinyAppUrl);
            }
        });
        setState(prevState => {
            return {
                ...prevState,
                workList: newData,
            };
        });
    };

    useEffect(() => {
        getOrderList();
    }, []);
    useEffect(() => {
        if (!socket) return;
        socket.addEventListener('message', (event) => {
            try {
                const messageData = JSON.parse(event.data);
                if (messageData.type === 'workstation-status') {
                    updateDataArray(messageData.data);
                }
            } catch (error) {
                console.error('消息解析错误:', error);
            }
        });
    }, [socket]);

    return (
        <div className={styles['container']}>
            <div className={styles['content']}>
                <div className={styles['title']}>
                    <div className={styles['h2']}>{t('menu.home.selectLocation')}</div>
                    <div className={styles['h3']}>{t('menu.home.titleText')}</div>
                </div>

                { state.loadingWork ? <div className={styles['loading']}><Spin/></div> : null }
                <div className={styles['work-list']}>
                    {
                        (state?.workList || []).length ?
                            <List
                                grid={{ gutter: 16, column: 3 }}
                                dataSource={state?.workList || []}
                                renderItem={item => {
                                    // 10:未使用且无需预约，20：未使用需预约,30：未使用预约中,40：使用中,overload：就是忙碌状态
                                    const status = item.usageStatus;
                                    const isIdle = [10].includes(status);
                                    const isInUse = [40].includes(status);
                                    const inBusiness = !isIdle && !isInUse || item.overload;

                                    return (
                                        <List.Item>
                                            <div className={styles['card']}>
                                                <div className={styles['header']}>
                                                    <div className={styles['id']}><span>{item.id}</span></div>
                                                    <div className={styles['name']} title={item.name}><div>{item.name}</div></div>
                                                    <div className={`${styles['dot']} ${isIdle ? styles['idle'] : (inBusiness ? styles['business'] : '')} `}>
                                                        <span></span>
                                                        {isIdle ? t('menu.home.app.idle') : (inBusiness ? t('menu.home.app.busy') : t('menu.home.app.inuse'))}
                                                    </div>
                                                </div>
                                                <div className={styles['sub-title']}>{t('menu.home.appList.title')}<span> ({t('menu.home.appList.desc').replace('{}', (item.workstationShinyappList || []).length)})</span></div>
                                                <div className={styles['app-list']}>
                                                    {
                                                        (item.workstationShinyappList || []).map(app => {
                                                            const status = app.usageStatus;
                                                            const idle = [10].includes(status);
                                                            const inUse = [20].includes(status);
                                                            const inOrder = [15].includes(status);;

                                                            return (
                                                                <div
                                                                    key={app.id}
                                                                    className={`${styles['app-item']} ${idle ? styles['idle'] : (inOrder ? styles['in-order'] : styles['business'])}`}
                                                                    onClick={handleApp.bind(null, item, app)}
                                                                >
                                                                    <div className={styles['app-status']}></div>
                                                                    <div className={styles['app-name']}>{app.shinyappName || '--'}</div>
                                                                </div>
                                                            );
                                                        })
                                                    }
                                                </div>
                                                <div className={styles['info']}>
                                                    <p>
                                                        {t('menu.home.queueNumber')} : <span>{item?.lineUpInfo?.userNumInfront}</span>
                                                        &nbsp;<span className={styles.Num}>{t('menu.home.people')}</span>
                                                    </p>
                                                    <p>
                                                        {t('menu.home.queueTime')} : <span>{secondsToMinutes(item?.lineUpInfo?.waitingTime)}</span>
                                                        &nbsp;<span className={styles.Num}>{t('menu.home.minute')}</span>
                                                    </p>
                                                </div>
                                                <div className={styles['desc']}>
                                                    <p>
                                                        Number of people queuing <span>{item?.lineUpInfo?.userNumInfront}</span>, queuing time{' '}
                                                        <span>{secondsToMinutes(item?.lineUpInfo?.waitingTime)}</span>
                                                    </p>
                                                </div>
                                            </div>
                                        </List.Item>
                                    );
                                }}
                            />
                            :
                            <p style={{ margin: '50px auto', color: '#AFB3B6' }}>{state.loadingWork ? '' : t('menu.home.available')}</p>
                    }
                </div>
            </div>

            {contextHolder}
        </div>
    )
}
